package com.dm.wallpaper.library.fraction;

import com.dm.wallpaper.library.utils.Log;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.ability.fraction.FractionAbility;

import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.Stack;


/*
 * Copyright (C) 2021 The Chinese Software International Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
public class FractionHelper {

    FractionAbility fractionAbility;
    FractionInfo nowShow;//当前helper中显示的fraction
    private HashMap<Class, FractionInfo> fractionMap = new HashMap();
    private static HashMap<FractionAbility, FractionHelper> fractionHelperHashMap = new HashMap<>();
    private HashMap<FractionAbility, Stack<Fraction>> fractionStack = new HashMap<>();

    private FractionHelper(FractionAbility fractionAbility) {
        this.fractionAbility = fractionAbility;
        fractionStack = new HashMap<>();
        fractionStack.put(fractionAbility, new Stack<>());
    }

    public static FractionHelper getInstance(FractionAbility fractionAbility) {
        FractionHelper fractionHelper = fractionHelperHashMap.get(fractionAbility);
        if (fractionHelper == null) {
//            synchronized (FractionHelper.class) {
//                if (fractionHelper == null) {
            fractionHelper = new FractionHelper(fractionAbility);
            fractionHelperHashMap.put(fractionAbility, fractionHelper);
//                }
//            }
        }
        return fractionHelper;
    }

    private FractionInfo getFractionInstance(Class<? extends Fraction> fractionClass) {
        try {
            FractionInfo fractionInfo = fractionMap.get(fractionClass);
            if (fractionInfo == null || fractionInfo.getViewId() == 0) {
                throw new NullPointerException("please use getFractionInstance(int compentId, Class<? extends Fraction> fractionClass) method to init");
            } else {
                if (fractionInfo.getFraction() == null) {
                    fractionInfo = new FractionInfo.Builder().setViewId(fractionInfo.getViewId()).setFraction(fractionClass.newInstance()).Build();
                    fractionMap.put(fractionClass, fractionInfo);
                }
                return fractionInfo;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public Fraction addFraction(int compentId, Class<? extends Fraction> fractionClass) {
        try {
            FractionInfo fractionInfo = fractionMap.get(fractionClass);
            if (fractionInfo == null || fractionInfo.getFraction() == null) {
                fractionInfo = new FractionInfo.Builder().setViewId(compentId).setFraction(fractionClass.newInstance()).Build();
                fractionMap.put(fractionClass, fractionInfo);
            }
            return fractionInfo.getFraction();
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("FractionHelper.addFraction([compentId, fractionClass]):63     错误:" + e.getMessage());
        }
        return null;
    }

    public void showFraction(Class<? extends Fraction> fractionClass) {
        if (fractionMap.get(fractionClass) == null) {
            throw new NullPointerException("please use showFraction(int compentId, Class<Fraction> fractionClass) to bind parent view");
        }
        if (nowShow != null) {
            fractionAbility.getFractionManager().startFractionScheduler().hide(nowShow.getFraction()).submit();
            fractionAbility.getFractionManager().startFractionScheduler().remove(nowShow.getFraction()).submit();
        }
        FractionInfo fractionInfo = getFractionInstance(fractionClass);
        fractionAbility.getFractionManager().startFractionScheduler().add(fractionInfo.getViewId(), fractionInfo.getFraction()).submit();
        fractionAbility.getFractionManager().startFractionScheduler().show(fractionInfo.getFraction()).submit();
        manageFractionStack(fractionInfo.getFraction());
        nowShow = getFractionInstance(fractionClass);
    }

    private void manageFractionStack(Fraction fraction) {
        if (fractionAbility != null) {
            int i = fractionStack.get(fractionAbility).search(fraction);
            Log.i("FractionHelper.manageFractionStack([fraction]):95        " + i);
            if (i == -1) {
                fractionStack.get(fractionAbility).push(fraction);
            } else {
                fractionStack.get(fractionAbility).pop();
                manageFractionStack(fraction);
            }
        }
    }

    public Fraction gotoLastFraction() {
        Fraction fraction;
        if (fractionAbility != null) {
            try {
                fractionStack.get(fractionAbility).pop();//弹出当前Fraction
                fraction = fractionStack.get(fractionAbility).pop();//获取前一个fraction
                showFraction(fraction.getClass());
                return fraction;
            } catch (EmptyStackException e) {
                return null;
            }
        } else {
            return null;
        }

    }

}
